//
// Created by konglinglong on 2020/9/14.
//

#include "../include/mschApi.h"
#include "chsch/bch.h"
#include "chsch/pch.h"
#include "chsch/dlsch.h"
#include "chsch/rach.h"
#include "chsch/ulsch.h"
#include "chres/pdcch.h"
#include "chres/pdsch.h"
#include "chres/pucch.h"
#include "chres/pusch.h"

S_RanMschContext *gpRanMschContext = NULL;

int32_t RAN_MSCH_Init(void)
{
    gpRanMschContext = OS_MemCalloc(1, sizeof(S_RanMschContext));
    IF_RETURN(==, NULL, gpRanMschContext, O5G_RC_ER, "RAN_MSCH_Init() OS_MemCalloc() error!\n");

    return O5G_RC_OK;
}

int32_t RAN_MSCH_Final(void)
{
    OS_MemFree(gpRanMschContext);

    return O5G_RC_OK;
}

void RAN_MSCH_SCH_PreProcess(S_RanL2CellInst *pCellInst, S_RanMschCellInst *pMschCellInst)
{
    S_RanSchRslt *pSchRslt;

    pCellInst->schSfnSlot = pCellInst->currAirSfnSlot;
    O5G_SfnSlot_Add(&pCellInst->schSfnSlot.sfn, &pCellInst->schSfnSlot.slot, pCellInst->slotNum, RAN_L2_SCH_ADV);
    pCellInst->schRsltIdx++;
    pCellInst->schRsltIdx %= RAN_DL_SCH_RSLT_RECORD_NUM_MAX;
    pSchRslt = &pCellInst->schRslt[pCellInst->schRsltIdx];
    pSchRslt->sfnSlot = pCellInst->schSfnSlot;

    RAN_MSCH_PDCCH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PDSCH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PUCCH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PUSCH_PreProcess(pCellInst, pMschCellInst);

    RAN_MSCH_BCH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PCH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_RACH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_ULSCH_PreProcess(pCellInst, pMschCellInst);
    RAN_MSCH_DLSCH_PreProcess(pCellInst, pMschCellInst);
}

void RAN_MSCH_SCH_PrintSchRslt(S_RanL2CellInst *pCellInst, S_RanMschCellInst *pMschCellInst)
{
    uint32_t loop;
    S_RanSchRslt *pSchRslt;

    pSchRslt = &pCellInst->schRslt[pCellInst->schRsltIdx];

    if (pSchRslt->bchExist)
    {
        CSP_LOG_DBG(RAN_MD_L2_COMM, "-------- MIB --------\n");
        CSP_LOG_DBG(RAN_MD_L2_COMM, "bchPayload = %#x\n", pSchRslt->bchSchRslt.bchPayload);
    }
    if (pSchRslt->ulschNum)
    {
        CSP_LOG_DBG(RAN_MD_L2_COMM, "-------- ULSCH[%u] --------\n", pSchRslt->ulschNum);
        for (loop = 0; loop < pSchRslt->ulschNum; loop++)
        {

        }
    }
    if (pSchRslt->dlschNum)
    {
        CSP_LOG_DBG(RAN_MD_L2_COMM, "-------- DLSCH[%u] --------\n", pSchRslt->dlschNum);
        for (loop = 0; loop < pSchRslt->dlschNum; loop++)
        {

        }
    }
}

void RAN_MSCH_SCH_PostProcess(S_RanL2CellInst *pCellInst, S_RanMschCellInst *pMschCellInst)
{
    RAN_MSCH_SCH_PrintSchRslt(pCellInst, pMschCellInst);

    RAN_MSCH_PDCCH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PDSCH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PUCCH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PUSCH_PostProcess(pCellInst, pMschCellInst);

    RAN_MSCH_BCH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_PCH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_RACH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_ULSCH_PostProcess(pCellInst, pMschCellInst);
    RAN_MSCH_DLSCH_PostProcess(pCellInst, pMschCellInst);
}

void RAN_MSCH_WakeUp(S_RanL2CellInst *pCellInst, S_RanMschCellInst *pMschCellInst)
{
    S_OsSelectInd indMsg;
    S_RanSchRslt *pSchRslt;

    pSchRslt = &pCellInst->schRslt[pCellInst->schRsltIdx];
    pSchRslt->sfnSlot = pCellInst->schSfnSlot;

    indMsg.ind = RAN_L2_INTRA_IND_MSG_TTI_IND;
    indMsg.sn = pCellInst->schRsltIdx;
    indMsg.data = (uintptr_t)pCellInst;
    OS_SelectSend(&pCellInst->dlLoTtiSelector, &indMsg);
}

void RAN_MSCH_SCH_TtiProcess(S_RanL2CellInst *pCellInst)
{
    S_RanMschCellInst *pMschCellInst;

    pMschCellInst = &gpRanMschContext->nbInst[pCellInst->nbIdx].cellInst[pCellInst->cellIdx];

    if (APP_STATE_RUNNING == pCellInst->appState)
    {
        RAN_MSCH_SCH_PreProcess(pCellInst, pMschCellInst);

        RAN_MSCH_BCH_Process(pCellInst, pMschCellInst);
        RAN_MSCH_PCH_Process(pCellInst, pMschCellInst);
        RAN_MSCH_RACH_Process(pCellInst, pMschCellInst);
        RAN_MSCH_DLSCH_Process(pCellInst, pMschCellInst);
        RAN_MSCH_ULSCH_Process(pCellInst, pMschCellInst);

        RAN_MSCH_SCH_PostProcess(pCellInst, pMschCellInst);
    }
    RAN_MSCH_WakeUp(pCellInst, pMschCellInst);
}

void RAN_MSCH_SCH_PtoProcess(S_RanL2CellInst *pCellInst)
{

}

void RAN_MSCH_ALG_PreProcess(S_RanL2CellInst *pCellInst, S_RanMschCellInst *pMschCellInst)
{

}

void RAN_MSCH_ALG_PostProcess(S_RanL2CellInst *pCellInst, S_RanMschCellInst *pMschCellInst)
{

}

void RAN_MSCH_ALG_TtiProcess(S_RanL2CellInst *pCellInst)
{
    S_RanMschCellInst *pMschCellInst;

    pMschCellInst = &gpRanMschContext->nbInst[pCellInst->nbIdx].cellInst[pCellInst->cellIdx];

    if (APP_STATE_RUNNING == pCellInst->appState)
    {
        RAN_MSCH_ALG_PreProcess(pCellInst, pMschCellInst);

        RAN_MSCH_ALG_PostProcess(pCellInst, pMschCellInst);
    }
}

void RAN_MSCH_ALG_PtoProcess(S_RanL2CellInst *pCellInst)
{

}
